#include "Skyplane.h"

namespace GeorgeLib
{

Skyplane::Skyplane(void)
{
}

Skyplane::~Skyplane(void)
{
	DELETE_ARR(vertices);
	DELETE_ARR(indices);
}

void Skyplane::init(int slices, float radius, float height, float hTile, float vTile)
{
	(slices < 1) ? (slices = 1) : (slices > 256) ? (slices = 256) : (slices);	
	numVertices = ( slices + 1 ) * ( slices + 1 );
	numIndices = slices * slices * 2 * 3;
	vertices = new Vertex[numVertices];
	indices = new unsigned short[numIndices];
	float planeSize = 2.0f * sqrtf((height*height) - (radius*radius));
	float delta = planeSize / (float)slices;
	float texDelta = 2.0f / (float)slices;
	for ( int z = 0; z <= slices; ++z )
	{
		for ( int x = 0; x <= slices; ++x )
		{
			float xDist = (-0.5f * planeSize) + ( (float)x * delta );
			float zDist = (-0.5f * planeSize) + ( (float)z * delta );
			float xHeight = ( xDist * xDist ) / height;
			float zHeight = ( zDist * zDist ) / height;
			float height = xHeight + zHeight;
			Vertex vertex;
			vertex.x = xDist;
			vertex.y = -height;
			vertex.z = zDist;

			// Calculate the texture coordinates
			vertex.u = hTile * ((float)x * texDelta * 0.5f);
			vertex.v = vTile * (1.0f - (float)z * texDelta * 0.5f);
			vertices[z * (slices+1) + x] = vertex;
		}
	}
	int index = 0;	// Indices	
	for (int i=0; i < slices; ++i)
	{
		for (int j=0; j < slices; ++j)
		{
			int startvert = (i * (slices+1) + j);		    
			indices[index++] = startvert;// tri 1
			indices[index++] = startvert + 1;
			indices[index++] = startvert + slices + 1;
			indices[index++] = startvert + 1; 	// tri 2
			indices[index++] = startvert + slices + 2;
			indices[index++] = startvert + slices + 1;
		}
	}
}

void Skyplane::draw(Texture texture, float size)
{
	glEnable(GL_TEXTURE_2D);

	glBindTexture(GL_TEXTURE_2D, texture.id);

	glPushMatrix();

		glTranslatef(0, size, 0);
		glScalef(.5,.5,.5); // scale size to half

		glBegin(GL_TRIANGLES);
			for(int i = 0; i < numIndices; ++i)
			{
				glColor3f(1,1,1);
				ushort index = indices[i];

				glTexCoord2f(vertices[index].u, vertices[index].v);
				glVertex3f(vertices[index].x, vertices[index].y, vertices[index].z);
			}
		glEnd();

	glPopMatrix();

	glDisable(GL_TEXTURE_2D);
}

void Skyplane::draw(MultiTexture texture, float size)
{
	glEnable(GL_TEXTURE_2D);

	// Set Textures
	for(uint i = 0; i < texture.texArray.size(); ++i)
	{
		glActiveTextureARB(GL_TEXTURE0_ARB + i);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture.texArray[i].id);
	}

	glPushMatrix();

		glTranslatef(0, size, 0);
		glScalef(.5,.5,.5); // scale size to half

		glBegin(GL_TRIANGLES);
			for(int i = 0; i < numIndices; ++i)
			{
				glColor3f(1,1,1);
				ushort index = indices[i];

				for(uint i = 0; i < texture.texArray.size(); ++i)
					glMultiTexCoord2fARB(GL_TEXTURE0_ARB + i, vertices[index].u, vertices[index].v);
				glVertex3f(vertices[index].x, vertices[index].y, vertices[index].z);
			}
		glEnd();

	glPopMatrix();

	for(uint i = 0; i < texture.texArray.size(); ++i)
	{
		glActiveTextureARB(GL_TEXTURE0_ARB + i);
		glDisable(GL_TEXTURE_2D);
	}
}

} // namespace GeorgeLib